import 'dart:convert';

import 'package:black_movice/api/api_urls.dart';
import 'package:black_movice/models/BackModel.dart';
import 'package:black_movice/models/FormModel.dart';
import 'package:black_movice/models/MoviceDetailsModel.dart';
import 'package:black_movice/models/MoviceListModel.dart';
import 'package:black_movice/models/UserModel.dart';
import 'package:black_movice/net/http_client.dart';
import 'package:black_movice/utils/Utils.dart';

class Api {
  static Api? _instance; //单例模式
  Api._(); //构造函数私有化
  static Api get instance {
    _instance ??= Api._();
    return _instance!;
  }

  // 发起请求的通用方法
  Future<BackModel> _sendRequest(
      String url, FormModel data, String requestType) async {
    try {
      BackModel backModel = await HttpClient.getInstance
          .request(url, data.toJson(), requestType: requestType);
      Utils.logDebug("返回的数据：${jsonEncode(backModel)}");
      return backModel;
    } catch (e) {
      Utils.logError("请求出错: $e");
      rethrow;
    }
  }

  // 测试 ping
  Future<BackModel> ping(FormModel data) async =>
      _sendRequest(ApiUrls.ping, data, "get");

  // 登录
  Future<UserModel> login(FormModel data) async {
    BackModel backModel = await _sendRequest(ApiUrls.login, data, "post");
    if (backModel.data == null) {
      // 手动抛出异常
      throw Exception('登录返回数据为空，无法解析 UserModel');
    }
    return UserModel.fromJson(backModel.data);
  }

  // 获取首页列表
  Future<List<MoviceListModel>> moviceList(FormModel data) async {
    BackModel backModel = await _sendRequest(ApiUrls.moviceList, data, "post");
    if (backModel.data == null) {
      throw Exception('简易电影列表返回为空');
    }
    return MoviceListModel.fromJsonList(backModel.data);
  }

  // 获取电影详情接口
  Future<MoviceDetailsModel> postMoviceDetails(FormModel data) async {
    BackModel backModel = BackModel();
    try {
      backModel = await _sendRequest(ApiUrls.MoviceDetailsModel, data, "post");
    } catch (e) {
      Utils.logError(e);
    }
    if (backModel.data == null) {
      throw Exception('电影详情列表返回为空');
    }
    return MoviceDetailsModel.fromJson(backModel.data);
  }
}
